package config

import (
	"gitee.com/yysf_xin/dplog/pkg/ck"
	"gitee.com/yysf_xin/dplog/pkg/extracter/java"
	"gitee.com/yysf_xin/go-common/db"
	"gitee.com/yysf_xin/go-common/tools"
	"gopkg.in/yaml.v3"
	"io"
	"net/http"
	"os"
	"time"
)

type Pattern struct {
	Id      int               `yaml:"id" json:"id"`
	Pattern string            `yaml:"pattern" json:"pattern,omitempty"`
	Type    string            `yaml:"type" json:"type,omitempty"`
	Options map[string]string `yaml:"options" json:"options,omitempty"`
}

type Dir struct {
	Name  string     `yaml:"name"`
	Dir   string     `yaml:"dir"`
	Items []*Pattern `yaml:"items"`
}
type Push struct {
	Url      string
	Template string
}

type Agg struct {
	Level     int
	Size      int
	Threshold float64
	Expire    Duration
	Span      Duration
}

var EnvStr = ""

type Duration time.Duration

func (d *Duration) UnmarshalYAML(value *yaml.Node) error {
	v, err := time.ParseDuration(value.Value)
	if err != nil {
		return err
	}
	*d = Duration(v)
	return nil
}

type ServerConfig struct {
	MaxBuf int        `yaml:"max_buf"`
	Db     *db.Config `yaml:"db"`

	ClickHouse *ck.Option `yaml:"click_house"`

	Java java.Opt `yaml:"java"`
	Dirs []*Dir   `yaml:"dirs"`
	Push *Push    `yaml:"push"`
	Agg  *Agg

	LogDir string `yaml:"logDir"`
}

type ClientConfig struct {
	db.Model
	Host   string `gorm:"index"`
	Ip     string `gorm:"index"`
	Config string `gorm:"size:1024"`
}

func ParseConfig(name string) (c *ServerConfig, err error) {
	c = &ServerConfig{}
	f, err := os.Open(name)
	if err == nil {
		var data []byte
		data, err = io.ReadAll(f)
		if err == nil {
			err = yaml.Unmarshal(data, c)
		}
	}
	return
}

type Handler struct {
	Db *db.Client
}

func NewHandler(db *db.Client) *Handler {
	if db.Cfg.Upgrade {
		var cfg ClientConfig
		err := db.DB.AutoMigrate(&cfg)
		if err != nil {
			tools.Log.Println(err)
		}
	}
	return &Handler{Db: db}
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	q := r.URL.Query()
	host := q.Get("host")
	ip := q.Get("ip")

	var cfg ClientConfig
	var err error

	err = h.Db.First(&cfg, "(host = ? or ip = ?)", host, ip).Error
	if err != nil && err != http.ErrNotSupported {
		cfg.Ip = ip
		cfg.Host = host
		err = h.Db.Save(&cfg).Error
	}
	if err != nil || cfg.Config == "" {
		tools.Log.Println("not found config", host, ip)
		w.WriteHeader(404)
	} else {
		w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
		_, _ = w.Write(tools.StringToBytes(cfg.Config))
	}
}
